home *** CD-ROM | disk | FTP | other *** search
/ Sprite 1984 - 1993 / Sprite 1984 - 1993.iso / src / kernel / dbg / ds3100.md / dbgIP.c < prev    next >
C/C++ Source or Header  |  1992-12-18  |  10KB  |  353 lines

  1. /* 
  2.  * dbgIP.c --
  3.  *
  4.  *    Routines to handle the IP/UDP protocol for the debugger. Validates
  5.  *    input packets and formats pacjkets for output.
  6.  *
  7.  * Copyright 1987 Regents of the University of California
  8.  * All rights reserved.
  9.  */
  10.  
  11. #ifndef lint
  12. static char rcsid[] = "$Header: /cdrom/src/kernel/Cvsroot/kernel/dbg/ds3100.md/dbgIP.c,v 9.3 91/08/02 17:40:32 jhh Exp $ SPRITE (Berkeley)";
  13. #endif not lint
  14.  
  15. #include <sprite.h>
  16. #include <dbg.h>
  17. #include <sys.h>
  18. #include <user/net.h>
  19. #include <machMon.h>
  20. #include <stdio.h>
  21.  
  22. extern    int    dbgTraceLevel;
  23.  
  24. /*
  25.  * Forward declarations.
  26.  */
  27.  
  28. #ifdef DEBUG
  29. static void     TestInputProc _ARGS_((int size, Net_IPHeader *headerPtr));
  30. static char *    ProtNumToName _ARGS_((unsigned int num));
  31. #endif /* DEBUG */
  32.  
  33.  
  34. /*
  35.  *----------------------------------------------------------------------
  36.  *
  37.  * Dbg_ValidatePacket --
  38.  *
  39.  *    This routine checks to see if an IP/UDP packet is proper. This
  40.  *    involves checking for the the proper sizes and that the packet 
  41.  *    has not been corrupted. The packet is checked to see if has the 
  42.  *    right UDP port. If the port matches then it is assumed that the 
  43.  *    packet is addressed to us.
  44.  *
  45.  *    Note: IP options processing and fragment reasssembly are not done.
  46.  *
  47.  * Results:
  48.  *    TRUE if packet processed successfully.
  49.  *
  50.  * Side effects:
  51.  *    None.
  52.  *
  53.  *----------------------------------------------------------------------
  54.  */
  55.  
  56. Boolean
  57. Dbg_ValidatePacket(size, ipPtr, lenPtr, dataPtrPtr, 
  58.         destIPAddrPtr, srcIPAddrPtr, srcPortPtr)
  59.  
  60.     int                size;        /* IP packet size in bytes. */
  61.     register Net_IPHeader    *ipPtr;        /* Ptr to IP packet buffer. */
  62.     int                *lenPtr;    /* Size of data in bytes.(out)*/
  63.     Address            *dataPtrPtr;    /* Address of data in the
  64.                          * in the packet. (out) */
  65.     Net_InetAddress        *destIPAddrPtr;    /* IP addr of this machine. 
  66.                          * (out) */
  67.     Net_InetAddress        *srcIPAddrPtr;    /* IP addr of sender. (out) */
  68.     unsigned int        *srcPortPtr;    /* UDP port from the sender
  69.                          * (needed to reply to the 
  70.                          * sender). */
  71. {
  72.     register Net_UDPHeader    *udpPtr;
  73.     register int        headerLenInBytes;
  74.     int                tmp;
  75.  
  76.     if (size < sizeof(Net_IPHeader)) {
  77.     if (dbgTraceLevel >= 4) {
  78.         Mach_MonPrintf("Dbg_ValidatePacket: Bad size %d\n", size);
  79.     }
  80.     return(FALSE);
  81.     }
  82.  
  83.     headerLenInBytes = ipPtr->headerLen * 4;
  84.     udpPtr = (Net_UDPHeader *) ((Address) ipPtr + headerLenInBytes);
  85.  
  86.     /*
  87.      * Validate the IP/UDP packet. The packet is checked for the following:
  88.      *  1) have a proper IP header length,
  89.      *  2) the total length of the packet must be larger than the IP header,
  90.      *  3) the IP checksum is ok,
  91.      *  4) the protocol is UDP,
  92.      *  5) the UDP packet length is proper,
  93.      *  6) the UDP dest. port matches the given port #,
  94.      *  7) the IP packet is not a fragment.
  95.      *
  96.      * The checks are done in order of importance and likelihood of being false.
  97.      * For instance, the header length should be validated before accessing
  98.      * fields in the header and it is more likely that the UDP port won't match
  99.      * than the packet is a fragment.
  100.      */
  101.     if (headerLenInBytes < sizeof(Net_IPHeader)) {
  102.     if (dbgTraceLevel >= 5) {
  103.         Mach_MonPrintf("Failed case 1: %d\n", headerLenInBytes);
  104.     }
  105.     return(FALSE);
  106.     } else if (Net_NetToHostShort(ipPtr->totalLen) < ipPtr->headerLen) {
  107.     if (dbgTraceLevel >= 5) {
  108.         Mach_MonPrintf("Failed case 2: %d, %d\n", 
  109.             Net_NetToHostShort(ipPtr->totalLen), ipPtr->headerLen);
  110.     }
  111.     return(FALSE);
  112.     } else if (Net_InetChecksum(headerLenInBytes, (Address) ipPtr) != 0) {
  113.     if (dbgTraceLevel >= 5) {
  114.         Mach_MonPrintf("Failed case 3 (IP checksum: %x)\n", 
  115.         ipPtr->checksum);
  116.     }
  117.     return(FALSE);
  118.     } else if (ipPtr->protocol != NET_IP_PROTOCOL_UDP) {
  119.     if (dbgTraceLevel >= 5) {
  120.         Mach_MonPrintf("Failed case 4: %d\n", ipPtr->protocol);
  121.     }
  122.     return(FALSE);
  123.     } else if (Net_NetToHostShort(udpPtr->len) < sizeof(Net_UDPHeader)) {
  124.     if (dbgTraceLevel >= 5) {
  125.         Mach_MonPrintf("Failed case 5: %d, %d\n",
  126.             Net_NetToHostShort(udpPtr->len), sizeof(Net_UDPHeader));
  127.     }
  128.     return(FALSE);
  129.     } else if (Net_NetToHostShort(udpPtr->destPort) < DBG_UDP_PORT) {
  130.     if (dbgTraceLevel >= 5) {
  131.         Mach_MonPrintf("Failed case 6: %d, %d\n", 
  132.             Net_NetToHostShort(udpPtr->destPort), DBG_UDP_PORT);
  133.     }
  134.     return(FALSE);
  135.     } else if ((ipPtr->flags & NET_IP_MORE_FRAGS) || (ipPtr->fragOffset != 0)) {
  136.     if (dbgTraceLevel >= 5) {
  137.         Mach_MonPrintf("Failed case 7: %d, %d\n",
  138.         (ipPtr->flags & NET_IP_MORE_FRAGS), (ipPtr->fragOffset != 0));
  139.     }
  140.     return(FALSE);
  141.     } 
  142.  
  143.     /*
  144.      * If the UDP packet was sent with a checksum, the checksum will be
  145.      * non-zero.
  146.      */
  147.     if (udpPtr->checksum != 0) {
  148.     Net_IPPseudoHdr        pseudoHdr;
  149.  
  150.     /*
  151.      * The checksum is computed for the IP "pseudo-header" and
  152.      * the UDP header and data. When the UDP checksum was calculated,
  153.      * the checksum field in the header was set to zero. When we 
  154.      * recalculate the value, we don't zero the field so the computed 
  155.      * value should be zero if the packet didn't get garbled.
  156.      */
  157.     bcopy((char*)&ipPtr->source, (char*)&pseudoHdr.source, 
  158.             sizeof(pseudoHdr.source));
  159.     bcopy((char*)&ipPtr->dest, (char*)&pseudoHdr.dest, 
  160.         sizeof(pseudoHdr.dest));
  161.     pseudoHdr.zero        = 0;
  162.     pseudoHdr.protocol    = ipPtr->protocol;
  163.     pseudoHdr.len        = udpPtr->len;
  164.     if (Net_InetChecksum2((int) Net_NetToHostShort(udpPtr->len),
  165.                 (Address) udpPtr, &pseudoHdr) != 0) {
  166.  
  167.         if (dbgTraceLevel >= 4) {
  168.         Mach_MonPrintf("Dbg_ValidatePacket: Bad UDP checksum: %x\n", 
  169.                 udpPtr->checksum);
  170.         }
  171.         return(FALSE);
  172.     }
  173.     }
  174.  
  175.     *lenPtr       = Net_NetToHostShort(udpPtr->len) - sizeof(Net_UDPHeader);
  176.     *dataPtrPtr       = ((Address) udpPtr) + sizeof(Net_UDPHeader);
  177.     bcopy((char*)&ipPtr->dest, (char*)&tmp, sizeof(int));
  178.     *destIPAddrPtr = Net_NetToHostInt(tmp);
  179.     bcopy((char*)&ipPtr->source, (char*)&tmp, sizeof(int));
  180.     *srcIPAddrPtr  = Net_NetToHostInt(tmp);
  181.     *srcPortPtr       = Net_NetToHostShort(udpPtr->srcPort);
  182.  
  183.     if (dbgTraceLevel >= 4) {
  184.     Mach_MonPrintf("Dbg_ValidatePacket: Good packet\n");
  185.     }
  186.     return(TRUE);
  187. }
  188.  
  189.  
  190. /*
  191.  *----------------------------------------------------------------------
  192.  *
  193.  * Dbg_FormatPacket --
  194.  *
  195.  *    Formats an IP/UDP packet for sending on the network.
  196.  *    The first Dbg_PacketHdrSize() bytes of *dataPtr must not be used -- 
  197.  *    this area is filled in with the IP and UDP headers.
  198.  *    The IP addresses and UDP port arguments are assumed to be in the
  199.  *    machine's native byte order. They are converted to network
  200.  *    byte order when the header is formatted.
  201.  *
  202.  *    Note: The IP header checksum is computed but the UDP checksum is not. 
  203.  *
  204.  * Results:
  205.  *    None.
  206.  *
  207.  * Side effects:
  208.  *    None.
  209.  *
  210.  *----------------------------------------------------------------------
  211.  */
  212.  
  213. void
  214. Dbg_FormatPacket(srcIPAddress, destIPAddress, destPort, dataSize, dataPtr)
  215.  
  216.     Net_InetAddress    srcIPAddress;    /* IP address of this machine. */
  217.     Net_InetAddress    destIPAddress;    /* IP address of destination. */
  218.     unsigned int    destPort;    /* UDP port of destination. */
  219.     int            dataSize;    /* Size in bytes of data in *dataPtr. */
  220.     Address        dataPtr;    /* Buffer containing data. */
  221. {
  222.     register Net_IPHeader     *ipPtr;        /* Ptr to IP header. */
  223.     register Net_UDPHeader     *udpPtr;    /* Ptr to UDP header. */
  224.     static    int        ident = 0;
  225.     int                tmp;
  226.  
  227.     ipPtr  = (Net_IPHeader *) dataPtr;
  228.     udpPtr = (Net_UDPHeader *) (dataPtr + sizeof(Net_IPHeader));
  229.  
  230.     ipPtr->version    = NET_IP_VERSION;
  231.     ipPtr->headerLen    = sizeof(Net_IPHeader) / 4;
  232.     ipPtr->typeOfService = 0;
  233.     ipPtr->totalLen    = Net_HostToNetShort(sizeof(Net_IPHeader) + 
  234.                     sizeof(Net_UDPHeader) + dataSize);
  235.     ipPtr->ident    = ident++;
  236.     ipPtr->fragOffset    = 0;
  237.     ipPtr->flags    = 0;
  238.     ipPtr->timeToLive    = NET_IP_MAX_TTL;
  239.     ipPtr->protocol    = NET_IP_PROTOCOL_UDP;
  240.     tmp = Net_HostToNetInt(srcIPAddress);
  241.     bcopy((char*)&tmp, (char*)&ipPtr->source, sizeof(int));
  242.     tmp = Net_HostToNetInt(destIPAddress);
  243.     bcopy((char*)&tmp, (char*)&ipPtr->dest, sizeof(int));
  244.     ipPtr->checksum    = 0;
  245.     ipPtr->checksum    = Net_InetChecksum(sizeof(Net_IPHeader),(Address)ipPtr);
  246.  
  247.     udpPtr->srcPort    = Net_HostToNetShort((short)DBG_UDP_PORT);
  248.     udpPtr->destPort    = Net_HostToNetShort((short)destPort);
  249.     udpPtr->len        = 
  250.         Net_HostToNetShort((short)(sizeof(Net_UDPHeader) + dataSize));
  251.     udpPtr->checksum    = 0;
  252. }
  253.  
  254.  
  255. /*
  256.  *----------------------------------------------------------------------
  257.  *
  258.  * Dbg_PacketHdrSize --
  259.  *
  260.  *    Returns the number of bytes that Dbg_FormatPacket expects to
  261.  *    format.
  262.  *
  263.  * Results:
  264.  *    The size of the packet header.
  265.  *
  266.  * Side effects:
  267.  *    None.
  268.  *
  269.  *----------------------------------------------------------------------
  270.  */
  271.  
  272. int
  273. Dbg_PacketHdrSize()
  274. {
  275.     return(sizeof(Net_IPHeader) + sizeof(Net_UDPHeader));
  276. }
  277.  
  278.  
  279. /*
  280.  *----------------------------------------------------------------------
  281.  *
  282.  * TestInputProc --
  283.  *
  284.  *    Debugging code to print the header of an IP datagram.
  285.  *
  286.  * Results:
  287.  *    None.
  288.  *
  289.  * Side effects:
  290.  *    None.
  291.  *
  292.  *----------------------------------------------------------------------
  293.  */
  294.  
  295. #ifdef DEBUG
  296.  
  297. static char srcAddr[18];
  298. static char destAddr[18];
  299.  
  300. static void
  301. TestInputProc(size, headerPtr)
  302.     int                size;
  303.     register Net_IPHeader       *headerPtr;
  304. {
  305.     unsigned short        checksum;
  306.  
  307.  
  308.     (void) Net_InetAddrToString(&(headerPtr->source), srcAddr);
  309.     (void) Net_InetAddrToString(&(headerPtr->dest), destAddr);
  310.  
  311.     Mach_MonPrintf("IP Packet: size = %d\n", size);
  312.     Mach_MonPrintf("Protocol, version:    %s, %d\n", 
  313.             ProtNumToName(headerPtr->protocol),
  314.             headerPtr->version);
  315.     Mach_MonPrintf("Src, dest addrs:    %s, %s\n", srcAddr, destAddr);
  316.     Mach_MonPrintf("Header, total len:    %d, %d\n", 
  317.             headerPtr->headerLen, headerPtr->totalLen);
  318.  
  319.     checksum = headerPtr->checksum, 
  320.     headerPtr->checksum = 0;
  321.     Mach_MonPrintf("checksum, recomp:    %x, %x\n", checksum, 
  322.         Net_InetChecksum((int)headerPtr->headerLen*4, 
  323.                     (Address)headerPtr));
  324.     Mach_MonPrintf("Frag flags, offset, ID:    %x, %d, %x\n", 
  325.             headerPtr->flags, headerPtr->fragOffset, 
  326.             headerPtr->ident);
  327.     Mach_MonPrintf("\n");
  328.  
  329.     return;
  330. }
  331.  
  332. static char *
  333. ProtNumToName(num) 
  334.     unsigned char num;
  335. {
  336.     switch (num) {
  337.     case NET_IP_PROTOCOL_IP:
  338.         return("IP");
  339.     case NET_IP_PROTOCOL_ICMP:
  340.         return("ICMP");
  341.     case NET_IP_PROTOCOL_TCP:
  342.         return("TCP");
  343.     case NET_IP_PROTOCOL_EGP:
  344.         return("EGP");
  345.     case NET_IP_PROTOCOL_UDP:
  346.         return("UDP");
  347.     default:
  348.         return("???");
  349.     }
  350. }
  351. #endif DEBUG
  352.  
  353.